package com.gis.visualization.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gis.visualization.config.exceptionhandler.VisException;
import com.gis.visualization.config.listener.FigureExcelListener;
import com.gis.visualization.entity.*;
import com.gis.visualization.entity.vo.*;
import com.gis.visualization.mapper.HistoryFigureMapper;
import com.gis.visualization.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gis.visualization.utils.wordcloud.CreateCloudImage;
import com.kennycason.kumo.WordCloud;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 历史人物表 服务实现类
 * </p>
 *
 * @author hqz
 * @since 2021-02-24
 */
@Service
public class HistoryFigureServiceImpl extends ServiceImpl<HistoryFigureMapper, HistoryFigure> implements HistoryFigureService {
    @Autowired
    private FigureLocationService locationService;

    @Autowired
    private HistorySummaryService summaryService;

    @Autowired
    private FigureLocationDescService locationDescService;

    @Autowired
    private VideoService videoService;

    @Autowired
    private OssService ossService;

    @Autowired
    private FigureTypeService typeService;

    @Override
    public Map<String, Object> pageFigureCondition(long current, long limit, FigureQueryVo figureQueryVo) {

        //人物表中条件查询数据
        String figureName = figureQueryVo.getFigureName();
        String city = figureQueryVo.getCity();
        String startTime = figureQueryVo.getStartTime();
        String endTime = figureQueryVo.getEndTime();

        QueryWrapper<HistoryFigure> figureQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(figureName)) {
            figureQueryWrapper.like("figure_name", figureName);
        }
        if (!StringUtils.isEmpty(city)) {
            figureQueryWrapper.eq("city", city);
        }

        if (!StringUtils.isEmpty(startTime)) {
            figureQueryWrapper.ge("birthday", startTime);
        }

        if (!StringUtils.isEmpty(endTime)) {
            figureQueryWrapper.le("birthday", endTime);
        }
        int total = baseMapper.selectCount(figureQueryWrapper);
        figureQueryWrapper.orderByDesc("gmt_create");
        figureQueryWrapper.last("limit " + (current - 1) * limit + "," + limit);
        //历史人物表条件查询的结果
        List<HistoryFigure> historyFigureList = baseMapper.selectList(figureQueryWrapper);

        List<FigurePageVo> figurePageVoList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        if (historyFigureList != null && historyFigureList.size() > 0) {
            historyFigureList.forEach(item -> {
//                添加人物信息
                FigurePageVo figurePageVo = new FigurePageVo();
                BeanUtils.copyProperties(item, figurePageVo);
//                添加人物地点信息
//                获取当前人物的地点列表
                List<FigureLocation> locationList = getLocations(item.getId());
                if (locationList != null) {
                    if (locationList.size() > 0) {
                        locationList.forEach(loc -> {
                            FigurePageItemVo figurePageItemVo = new FigurePageItemVo();
                            BeanUtils.copyProperties(loc, figurePageItemVo);
                            figurePageItemVo.setDescription(getLocDesc(loc.getId()));
                            figurePageVo.getChildren().add(figurePageItemVo);
                        });
                    }
                }
                figurePageVoList.add(figurePageVo);
            });
//            封装集合的长度
            map.put("total", total);
            map.put("records", figurePageVoList);
            return map;
        } else {//没人人物数据
            map.put("total", 0);
            map.put("records", new ArrayList<FigurePageVo>());
            return map;
        }
    }

    @Override
    public void deleteFigure(String figureId) {
//        删除人物表中的人物
        baseMapper.deleteById(figureId);
//        查询人物下的所有地点
        QueryWrapper<FigureLocation> locationQueryWrapper = new QueryWrapper<>();
        locationQueryWrapper.eq("figure_id", figureId);
        List<FigureLocation> locationList = locationService.list(locationQueryWrapper);
        List<String> locationIdList = new ArrayList<>();
        if (locationList.size() > 0) {
            locationList.forEach(item -> {
                locationIdList.add(item.getId());
            });
            //        删除地点的描述
            locationDescService.removeByIds(locationIdList);
            //        删除人物地点表中的所有地点
            locationService.removeByIds(locationIdList);
        }

        HistorySummary historySummary = summaryService.getById(figureId);
        if (historySummary != null) {
            String videoSourceId = historySummary.getVideoSourceId();
            if (!StringUtils.isEmpty(videoSourceId)) {
                //        删除人物视频
                videoService.removeALYVideo(videoSourceId);
            }
            //删除人物总结
            summaryService.removeById(figureId);
        }
    }

    @Override
    @Transactional(rollbackFor = VisException.class)
    public void figureFromExcel(MultipartFile file,
                                HistoryFigureService figureService,
                                FigureLocationService locationService,
                                FigureLocationDescService locationDescService,
                                HistorySummaryService summaryService,
                                OssService ossService) {
        try {
            InputStream fileInputStream = file.getInputStream();
            FigureExcelListener figureExcelListener = new FigureExcelListener(figureService
                    , locationService, locationDescService, summaryService, ossService);
            //            调用excel 的读取
            EasyExcel.read(fileInputStream, FigureExcelVo.class, figureExcelListener).sheet().doRead();
        } catch (Exception e) {
            e.printStackTrace();
            throw new VisException(20001, "读取excel失败,请检查excel中内容格式是否标准");
        }
    }

    @Override
    public List<Map<String, Object>> getFuzzyNames(String n) {
        QueryWrapper<HistoryFigure> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(n)) {
            wrapper.like("figure_name", n);
        }
        wrapper.select("id", "figure_name");
        List<HistoryFigure> historyFigureList = baseMapper.selectList(wrapper);
        List<Map<String, Object>> names = new ArrayList<>();
        historyFigureList.forEach(item -> {
            if (!StringUtils.isEmpty(item.getFigureName())) {
                Map<String, Object> map = MapUtil.newHashMap();
                map.put("figureName", item.getFigureName());
                map.put("id", item.getId());
                names.add(map);
            }
        });
        return names;
    }

    @Override
    public Map<String, Integer> getNames() {
        QueryWrapper<HistoryFigure> wrapper = new QueryWrapper<>();
        wrapper.select("figure_name");
        List<HistoryFigure> figures = baseMapper.selectList(wrapper);
        HashMap<String, Integer> map = new HashMap<>();
        StringBuilder str = new StringBuilder();
        for (HistoryFigure figure : figures) {
            if (StringUtils.isEmpty(figure.getFigureName())) {
                continue;
            }
            if (figure.getFigureName().contains("欧阳")) {
                str.append(figure.getFigureName().substring(0, 2));
            } else {
                str.append(figure.getFigureName().charAt(0));
            }
            if (!map.containsKey(str.toString())) {
                map.put(str.toString(), 1);
            } else {
                map.put(str.toString(), map.get(str.toString()) + 1);
            }
            str.setLength(0);
        }
        // List<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
        // Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
        //     @Override
        //     public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
        //         return o2.getValue().compareTo(o1.getValue());
        //     }
        // });
        return MapUtil.sortByValue(map, true);
    }

    @Override
    public Map<String, Integer> nameWordCloudByTimeCity(TimeCityVo timeCityVo) {

        String startYear = timeCityVo.getStartYear();
        String endYear = timeCityVo.getEndYear();
        String city = timeCityVo.getCity();
        LambdaQueryWrapper<HistoryFigure> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(HistoryFigure::getFigureName);
        if (StrUtil.isNotEmpty(startYear)) {
            wrapper.ge(HistoryFigure::getBirthday, startYear);
        }
        if (StrUtil.isNotEmpty(endYear)) {
            wrapper.le(HistoryFigure::getBirthday, endYear);
        }
        if (StrUtil.isNotEmpty(city)) {
            wrapper.eq(HistoryFigure::getCity, city);
        }
        //根据时间，城市条件获得了所有人名
        List<HistoryFigure> figures = baseMapper.selectList(wrapper);
        HashMap<String, Integer> map = MapUtil.newHashMap();
        //姓氏
        StringBuilder fName = new StringBuilder();
        //临时存储人物姓名
        StringBuilder tempName = new StringBuilder();
        //遍历 分离出姓氏
        for (HistoryFigure figure : figures) {
            tempName.append(figure.getFigureName());
            if (StrUtil.isEmpty(tempName)) {
                continue;
            }
            //截取姓氏
            if (tempName.toString().contains("欧阳")) {
                fName.append(tempName.substring(0, 2));
            } else {
                fName.append(tempName.charAt(0));
            }

            if (!map.containsKey(fName.toString())) {
                map.put(fName.toString(), 1);
            } else {
                map.put(fName.toString(), map.get(fName.toString()) + 1);
            }
            fName.setLength(0);
            tempName.setLength(0);
        }

        return MapUtil.sortByValue(map, true);
    }

    @Override
    public List<Map<String, Object>> getSexRatioByTimeCity(TimeCityVo timeCityVo) {
        return baseMapper.getSexRatioByTimeCity(timeCityVo);
    }

    @Override
    public List<Map<String, Object>> getFigureLocAndLat() {

        List<HistoryFigure> historyFigureList = baseMapper.selectList(new LambdaQueryWrapper<HistoryFigure>()
                .select(HistoryFigure::getLongitude, HistoryFigure::getLatitude)
                .isNotNull(HistoryFigure::getLongitude)
                .isNotNull(HistoryFigure::getLatitude)
        );

        // List<Map<String,Object>> mapList = new ArrayList<>();
        List<Map<String, Object>> mapList = historyFigureList.parallelStream().map(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("lng", item.getLongitude());
            map.put("lat", item.getLatitude());
            return map;
        }).collect(Collectors.toList());


        return mapList;
    }

    @Override
    public Map<String, Object> getFigureClassLocAndLat() {
        //查出所有的人物类型
        List<FigureType> figureTypeList = typeService.list(null);
        //封装结果
        Map<String, Object> resultMap = new HashMap<>();
        //查询出所有的人物数据
        List<HistoryFigure> historyFigureList = baseMapper.selectList(new LambdaQueryWrapper<HistoryFigure>()
                .select(HistoryFigure::getLongitude, HistoryFigure::getLatitude, HistoryFigure::getTypes)
                .isNotNull(HistoryFigure::getLongitude)
                .isNotNull(HistoryFigure::getLatitude)
                .isNotNull(HistoryFigure::getTypes));
        figureTypeList.forEach(item -> {
            List<Map<String, Object>> tempMapList = new ArrayList<>();
            historyFigureList
                    .parallelStream()
                    //过滤出类型包含当前项的
                    .filter(figure -> figure.getTypes().contains(item.getFType()))
                    //返回经纬度
                    .forEach(figure -> {
                        Map<String, Object> LocAndLatMap = new HashMap<>();
                        LocAndLatMap.put("lng", figure.getLongitude());
                        LocAndLatMap.put("lat", figure.getLatitude());
                        tempMapList.add(LocAndLatMap);
                    });
            resultMap.put(item.getFType(), tempMapList);
        });
        return resultMap;
    }

    @Override
    public List<Map<String, Object>> getAgeDistributionByTimeCity(TimeCityVo timeCityVo) {
        return baseMapper.getAgeDistributionByTimeCity(timeCityVo);
    }

    @Override
    public String getNameWordCloudImg(Map<String, Integer> list) {
        WordCloud wordCloud = CreateCloudImage.nameCloudImage(list);
        //临时
        InputStream in = null;
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            wordCloud.writeToStreamAsPNG(out);
            byte[] bookByteAry = out.toByteArray();
            in = new ByteArrayInputStream(bookByteAry);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ossService.uploadImgFileName(in, "config/姓氏词云图.png");
    }

    @Override
    public List<Map<String, Object>> getAgeDistribution() {
        return baseMapper.getAgeDistribution();
    }

    @Override
    public List<TreeMap<String, Object>> getFigureCity() {
        return baseMapper.getFigureCity();
    }

    @Override
    public List<Map<String, Object>> getSexRatio() {
        return baseMapper.getSexRatio();
    }

    @Override
    public List<Map<String, Object>> getFigureTypes() {
        return baseMapper.getFigureTypes();
    }

    @Override
    public Map<String, Object> getMinMaxYear() {
        Map<String, Object> year = baseMapper.getMinMaxYear();
        String minYear = year.get("minYear").toString();
        String maxYear = year.get("maxYear").toString();
        year.clear();
        year.put("minYear", minYear.split("-")[0]);
        year.put("maxYear", maxYear.split("-")[0]);
        return year;
    }


    @Override
    public List<TreeMap<String, Object>> getFigureCityByTime(TimeCityVo timeCityVo) {
        return baseMapper.getFigureCityByTime(timeCityVo);
    }

    @Override
    public List<Map<String, Object>> getFigureTypesByTimeCity(TimeCityVo timeCityVo) {
        return baseMapper.getFigureTypesByTimeCity(timeCityVo);
    }


    private List<FigureLocation> getLocations(String figureId) {
        QueryWrapper<FigureLocation> locationQueryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(figureId)) {
            locationQueryWrapper.eq("figure_id", figureId);
        }
        locationQueryWrapper.orderByAsc("sort");
        return locationService.list(locationQueryWrapper);
    }

    private String getLocDesc(String locationId) {
        FigureLocationDesc locationDesc = locationDescService.getById(locationId);
        if (locationDesc == null) {
            return "";
        }

        if (StringUtils.isEmpty(locationDesc.getDescription())) {
            return "";
        } else {
            return locationDesc.getDescription();
        }
    }


}
